<script lang="ts" setup>
import { toInteger } from 'lodash-es'
import type { FormInst, FormItemRule, FormRules } from 'naive-ui'
import { useUserStore } from '@/store/modules'
import { emailVerify } from '@/api/code'
import { userModifyAccount } from '@/api/user'

const { userInfo, logout, getUserInfo } = useUserStore()

/** 对话框 */
enum DialogType {
  Null = '',
  Phone = 'phone',
  Email = 'email',
  Password = 'password',
}
interface Dialog {
  visible: boolean
  title: string
  type: DialogType

  phone: string
  email: string
  newEmail: string
  newPassword: string
  password: string
  code: string

  timer: number | string
  codeText: string
}
const dialog = ref<Dialog>({
  visible: false,
  title: '',
  type: DialogType.Null, // 对话框类型

  phone: '', // 手机号/登陆账号
  email: '', // 邮箱地址
  newEmail: '', // 新邮箱地址
  newPassword: '', // 新密码
  password: '', // 确认密码
  code: '', // 验证码

  timer: '', // 定时器
  codeText: '获取验证码', // 验证码文本显示
})

function openDialog(type: DialogType) { // 打开对话框
  dialog.value.type = type
  dialog.value.visible = true
  dialog.value.phone = userInfo.phone
  dialog.value.email = userInfo.email
  switch (type) {
    case 'phone':
      dialog.value.title = '修改手机号/登录账号'
      break
    case 'email':
      dialog.value.title = '修改绑定邮箱'
      break
    case 'password':
      dialog.value.title = '重置密码'
      break
  }
}
function closeDialog() { // 关闭对话框
  clearInterval(dialog.value.timer) // 清空计时器
  dialog.value = {
    visible: false,
    title: '',
    type: DialogType.Null, // 对话框类型

    phone: '', // 手机号/登陆账号
    email: '', // 邮箱地址
    newEmail: '', // 新邮箱地址
    newPassword: '', // 新密码
    password: '', // 确认密码
    code: '', // 验证码

    timer: '', // 定时器
    codeText: '获取验证码', // 验证码文本显示
  }
}
/** 对话框表单 */
const dialogFormRef = ref<FormInst | null>(null)

function submitDialog() { // 提交对话框表单
  dialogFormRef.value?.validate((errors) => {
    if (!errors)
      modifyAccount()
    else
      window.$message?.warning('请输入必填项')
  })
}
async function modifyAccount() { // 修改账户接口
  const { code, msg } = await userModifyAccount(dialog.value)
  if (code === 0) {
    switch (dialog.value.type) {
      case 'phone':
        logout()
        closeDialog()
        window.$message?.success('修改手机号，请退出重新登陆')
        break
      case 'password':
        logout()
        closeDialog()
        window.$message?.success('重置密码成功，请退出重新登陆')
        break
      default:
        closeDialog()
        window.$message?.success(msg)
        getUserInfo()
        break
    }
  }
}

// 发送验证码
async function sendCode(email: string) {
  if (dialog.value.timer) { // 验证码已发送后不能再发送
    return
  }
  const { code, msg } = await emailVerify({ email })
  if (code === 0) {
    window.$message?.success(msg)
    setCodeTimer() // 设置定时器
  }
}
// 设置计时器
function setCodeTimer() {
  let ss = 300 // 5分钟
  dialog.value.codeText = formatDate(ss)

  dialog.value.timer = window.setInterval(() => { // 开始计时
    ss--
    dialog.value.codeText = formatDate(ss)
    if (ss === 0) { // 计时器结束
      dialog.value.codeText = '重新发送'
      clearInterval(dialog.value.timer) // 清空计时器
      dialog.value.timer = ''
    }
  }, 1000)
}
// 格式化时间
function formatDate(ssNum: number) {
  let min = 0 // 初始化分钟
  let ss = 0 // 初始化秒数
  if (ssNum > 60) { // 如果秒数大于60，将秒数转换成分钟数
    min = toInteger(ssNum / 60) // 获取分钟，除以60取整数，得到整数分钟
    ss = toInteger(ssNum % 60)// 获取秒数，秒数取佘，得到整数秒数
  }
  else {
    ss = toInteger(ssNum % 60)// 获取秒数，秒数取佘，得到整数秒数
  }
  return `${min.toString().padStart(2, '0')} : ${ss.toString().padStart(2, '0')}`
}
/** 对话框表单校验规则 */
const rules: FormRules = {
  phone: [{
    required: true,
    trigger: 'blur',
    validator(_rule: FormItemRule, value: string) {
      const phoneTest = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/
      if (!value)
        return new Error('请输入新的手机号/登录账号')
      if (!phoneTest.test(value))
        return new Error('请输入正确的手机号')
      return true
    },
  }],
  newEmail: [{
    required: true,
    trigger: 'blur',
    validator(_rule: FormItemRule, value: string) {
      const emailTest = /^[A-Za-z0-9\u4E00-\u9FA5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
      if (!value)
        return new Error('请输入新邮箱地址')
      if (!emailTest.test(value))
        return new Error('请输入正确的邮箱地址')
      return true
    },
  }],
  newPassword: [{ required: true, trigger: 'blur', message: '请输入新密码' }],
  password: [{
    required: true,
    trigger: 'blur',
    validator(_rule: FormItemRule, value: string) {
      if (!value)
        return new Error('请输入确认密码')
      if (value !== dialog.value.newPassword)
        return new Error('两次输入密码不一致')
      return true
    },
  }],
}
</script>

<template>
  <n-form mt-20>
    <n-form-item label="手机号/登陆账号">
      <span text-16 tracking-widest>{{ userInfo.phone }}</span>
      <n-button strong type="primary" size="medium" ml-20 @click="openDialog(DialogType.Phone)">
        修 改
      </n-button>
    </n-form-item>
    <n-form-item label="绑定邮箱">
      <span text-16 tracking-widest>{{ userInfo.email }}</span>
      <n-button strong type="primary" size="medium" ml-20 @click="openDialog(DialogType.Email)">
        修 改
      </n-button>
    </n-form-item>
    <n-form-item label="账号密码">
      <span text-16 tracking-widest>*********</span>
      <n-button strong type="primary" size="medium" ml-20 @click="openDialog(DialogType.Password)">
        修 改
      </n-button>
    </n-form-item>
  </n-form>
  <Cdialog v-model:visible="dialog.visible" :title="dialog.title">
    <n-form ref="dialogFormRef" :model="dialog" :rules="rules">
      <n-form-item label="绑定邮箱">
        {{ userInfo.email }}
      </n-form-item>
      <n-form-item v-if="dialog.type === 'phone'" label="手机号/登陆账号" path="phone">
        <n-input-number v-model:value="dialog.phone" :show-button="false" placeholder="请输入新手机手机号" w-full clearable />
      </n-form-item>
      <n-form-item v-if="dialog.type === 'email'" label="新邮箱地址" path="newEmail">
        <n-input v-model:value="dialog.newEmail" placeholder="请输入新新邮箱地址" w-full clearable />
      </n-form-item>
      <template v-if="dialog.type === 'password'">
        <n-form-item label="新账号密码" path="newPassword">
          <n-input v-model:value="dialog.newPassword" type="password" show-password-on="mousedown" placeholder="请输入新的账号密码" w-full />
        </n-form-item>
        <n-form-item label="确认密码" path="password">
          <n-input v-model:value="dialog.password" type="password" show-password-on="mousedown" placeholder="请再次输入确认密码" w-full />
        </n-form-item>
      </template>
      <n-form-item label="邮箱验证码">
        <n-input-group>
          <n-input v-model:value="dialog.code" type="text" placeholder="请输入获取的验证码" />
          <n-button type="primary" :focusable="false" :disabled="dialog.timer ? true : false" @click="sendCode(userInfo.email)">
            {{ dialog.codeText }}
          </n-button>
        </n-input-group>
      </n-form-item>
    </n-form>
    <template #footer>
      <div f-c-c>
        <n-button mr-5 b-rd-5 size="medium" @click="closeDialog">
          <n-icon cursor-pointer size="16">
            <icon-mdi:cancel />
          </n-icon>
          <span ml-2>取 消</span>
        </n-button>
        <n-button ml-5 b-rd-5 type="primary" size="medium" @click="submitDialog">
          <n-icon cursor-pointer size="16">
            <icon-mdi:checkbox-marked-circle-outline />
          </n-icon>
          <span ml-2>确 定</span>
        </n-button>
      </div>
    </template>
  </Cdialog>
</template>

<style lang="scss" scoped>
:deep(.n-form-item) {
  margin-bottom: 20px;
  .n-form-item-label {
    font-weight: bold;
    color: #909399;
  }
}
</style>
